/*!
 * LMV v6.4.1
 * 
 * Copyright 2019 Autodesk, Inc.
 * All rights reserved.
 * 
 * This computer source code and related instructions and comments are the
 * unpublished confidential and proprietary information of Autodesk, Inc.
 * and are protected under Federal copyright and state trade secret law.
 * They may not be disclosed to, copied or used by any third party without
 * the prior written consent of Autodesk, Inc.
 * 
 * Autodesk Forge Viewer Usage Limitations:
 * 
 * The Autodesk Forge viewer can only be used to view files generated by
 * Autodesk Forge services. The Autodesk Forge Viewer JavaScript must be
 * delivered from an Autodesk hosted URL.
 */
Autodesk.Extensions.Hyperlink =
/******/ (function(modules) { // webpackBootstrap
/******/ 	// The module cache
/******/ 	var installedModules = {};
/******/
/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {
/******/
/******/ 		// Check if module is in cache
/******/ 		if(installedModules[moduleId]) {
/******/ 			return installedModules[moduleId].exports;
/******/ 		}
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = installedModules[moduleId] = {
/******/ 			i: moduleId,
/******/ 			l: false,
/******/ 			exports: {}
/******/ 		};
/******/
/******/ 		// Execute the module function
/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ 		// Flag the module as loaded
/******/ 		module.l = true;
/******/
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/
/******/
/******/ 	// expose the modules object (__webpack_modules__)
/******/ 	__webpack_require__.m = modules;
/******/
/******/ 	// expose the module cache
/******/ 	__webpack_require__.c = installedModules;
/******/
/******/ 	// define getter function for harmony exports
/******/ 	__webpack_require__.d = function(exports, name, getter) {
/******/ 		if(!__webpack_require__.o(exports, name)) {
/******/ 			Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/ 		}
/******/ 	};
/******/
/******/ 	// define __esModule on exports
/******/ 	__webpack_require__.r = function(exports) {
/******/ 		if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ 			Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ 		}
/******/ 		Object.defineProperty(exports, '__esModule', { value: true });
/******/ 	};
/******/
/******/ 	// create a fake namespace object
/******/ 	// mode & 1: value is a module id, require it
/******/ 	// mode & 2: merge all properties of value into the ns
/******/ 	// mode & 4: return value when already ns object
/******/ 	// mode & 8|1: behave like require
/******/ 	__webpack_require__.t = function(value, mode) {
/******/ 		if(mode & 1) value = __webpack_require__(value);
/******/ 		if(mode & 8) return value;
/******/ 		if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/ 		var ns = Object.create(null);
/******/ 		__webpack_require__.r(ns);
/******/ 		Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/ 		if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/ 		return ns;
/******/ 	};
/******/
/******/ 	// getDefaultExport function for compatibility with non-harmony modules
/******/ 	__webpack_require__.n = function(module) {
/******/ 		var getter = module && module.__esModule ?
/******/ 			function getDefault() { return module['default']; } :
/******/ 			function getModuleExports() { return module; };
/******/ 		__webpack_require__.d(getter, 'a', getter);
/******/ 		return getter;
/******/ 	};
/******/
/******/ 	// Object.prototype.hasOwnProperty.call
/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ 	// __webpack_public_path__
/******/ 	__webpack_require__.p = "";
/******/
/******/
/******/ 	// Load entry module and return exports
/******/ 	return __webpack_require__(__webpack_require__.s = "./extensions/Hyperlink/Hyperlink.js");
/******/ })
/************************************************************************/
/******/ ({

/***/ "./extensions/Hyperlink/Hyperlink.css":
/*!********************************************!*\
  !*** ./extensions/Hyperlink/Hyperlink.css ***!
  \********************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {


var content = __webpack_require__(/*! !../../node_modules/css-loader!./Hyperlink.css */ "./node_modules/css-loader/index.js!./extensions/Hyperlink/Hyperlink.css");

if(typeof content === 'string') content = [[module.i, content, '']];

var transform;
var insertInto;



var options = {"hmr":true}

options.transform = transform
options.insertInto = undefined;

var update = __webpack_require__(/*! ../../node_modules/style-loader/lib/addStyles.js */ "./node_modules/style-loader/lib/addStyles.js")(content, options);

if(content.locals) module.exports = content.locals;

if(false) {}

/***/ }),

/***/ "./extensions/Hyperlink/Hyperlink.js":
/*!*******************************************!*\
  !*** ./extensions/Hyperlink/Hyperlink.js ***!
  \*******************************************/
/*! exports provided: HyperlinkExtension */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HyperlinkExtension", function() { return HyperlinkExtension; });
/* harmony import */ var _HyperlinkTool__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./HyperlinkTool */ "./extensions/Hyperlink/HyperlinkTool.js");
/* harmony import */ var _Hyperlink_css__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Hyperlink.css */ "./extensions/Hyperlink/Hyperlink.css");
/* harmony import */ var _Hyperlink_css__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_Hyperlink_css__WEBPACK_IMPORTED_MODULE_1__);


var av = Autodesk.Viewing;
var aveh = AutodeskNamespace('Autodesk.Viewing.Extensions.Hyperlink');




/**
                                    * Enhances 2D models by adding in-canvas tooltips that on click will navigate 
                                    * the user to another 2D or 3D model.
                                    * 
                                    * The extension id is: `Autodesk.Hyperlink`
                                    * 
                                    * @example
                                    *   viewer.loadExtension('Autodesk.Hyperlink')
                                    * 
                                    * @memberof Autodesk.Viewing.Extensions
                                    * @alias Autodesk.Viewing.Extensions.HyperlinkExtension
                                    * @see {@link Autodesk.Viewing.Extension} for common inherited methods.
                                    * @constructor
                                    */
function HyperlinkExtension(viewer, options) {
  av.Extension.call(this, viewer, options);
  this.tool = null;
  this.name = 'hyperlink';
};

HyperlinkExtension.prototype = Object.create(av.Extension.prototype);
HyperlinkExtension.prototype.constructor = HyperlinkExtension;

/**
                                                                * Registers the hyperlink tool that will intercept pointer events to provide
                                                                * hyperlinks next to specific nodes in the model.
                                                                * 
                                                                * @alias Autodesk.Viewing.Extensions.HyperlinkExtension#load
                                                                */
HyperlinkExtension.prototype.load = function () {
  var toolConfig = this.options || {};
  this.tool = new _HyperlinkTool__WEBPACK_IMPORTED_MODULE_0__["HyperlinkTool"](this.viewer, toolConfig);
  this.viewer.toolController.registerTool(this.tool);
  this.viewer.toolController.activateTool(this.tool.getName());
  return true;
};

/**
    * Unregisters the hyperlink tool.
    * 
    * @alias Autodesk.Viewing.Extensions.HyperlinkExtension#unload
    */
HyperlinkExtension.prototype.unload = function () {
  this.viewer.toolController.deactivateTool(this.tool.getName());
  this.viewer.toolController.deregisterTool(this.tool);
  this.tool = null;
  return true;
};

HyperlinkExtension.prototype.activate = function () {
  return true;
};

HyperlinkExtension.prototype.deactivate = function () {
  return false;
};
aveh.HyperlinkExtension = HyperlinkExtension;
av.theExtensionManager.registerExtension('Autodesk.Hyperlink', HyperlinkExtension);

/***/ }),

/***/ "./extensions/Hyperlink/HyperlinkBack.js":
/*!***********************************************!*\
  !*** ./extensions/Hyperlink/HyperlinkBack.js ***!
  \***********************************************/
/*! exports provided: HyperlinkBack */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HyperlinkBack", function() { return HyperlinkBack; });


/**
               * Back button added when user navigates to a new sheet using an hyperlink.
               * 
               * @param {*} hyperlinkTool 
               * @param {*} viewer 
               * @param {*} link 
               */function _classCallCheck(instance, Constructor) {if (!(instance instanceof Constructor)) {throw new TypeError("Cannot call a class as a function");}}function _defineProperties(target, props) {for (var i = 0; i < props.length; i++) {var descriptor = props[i];descriptor.enumerable = descriptor.enumerable || false;descriptor.configurable = true;if ("value" in descriptor) descriptor.writable = true;Object.defineProperty(target, descriptor.key, descriptor);}}function _createClass(Constructor, protoProps, staticProps) {if (protoProps) _defineProperties(Constructor.prototype, protoProps);if (staticProps) _defineProperties(Constructor, staticProps);return Constructor;}
var HyperlinkBack = /*#__PURE__*/function () {

  function HyperlinkBack(hyperlinkTool, viewer, itemBack) {var _this = this;_classCallCheck(this, HyperlinkBack);
    this.viewer = viewer;

    this.container = document.createElement("div");
    this.container.classList.add("docking-panel-primary-button");
    this.container.classList.add("hyperlink-back");
    viewer.container.appendChild(this.container);

    this.backButton = document.createElement("div");
    this.backButton.className = "hyperlink-back-button";
    this.backButton.setAttribute("data-i18n", "Back");
    this.backButton.textContent = av.i18n.translate("Back");
    this.container.appendChild(this.backButton);
    this.backButton.addEventListener('click', function () {
      _this.uninitialize();
      viewer.__hyperlinkBack = null;
      if (hyperlinkTool.panel) {
        hyperlinkTool.panel.uninitialize();
        hyperlinkTool.panel = null;
      }
      hyperlinkTool.navigateToLink(null, itemBack);
    });

    this.closer = document.createElement("div");
    this.closer.classList.add("docking-panel-close");
    this.closer.classList.add("hyperlink-back-closer");
    this.container.appendChild(this.closer);
    this.closer.addEventListener('click', function () {
      _this.uninitialize();
      viewer.__hyperlinkBack = null;
    });

  }_createClass(HyperlinkBack, [{ key: "uninitialize", value: function uninitialize()

    {
      this.viewer.container.removeChild(this.container);
      this.container = null;
    } }]);return HyperlinkBack;}();

;

/***/ }),

/***/ "./extensions/Hyperlink/HyperlinkGui.js":
/*!**********************************************!*\
  !*** ./extensions/Hyperlink/HyperlinkGui.js ***!
  \**********************************************/
/*! exports provided: HyperlinkPanel */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HyperlinkPanel", function() { return HyperlinkPanel; });
/* harmony import */ var _HyperlinkBack__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./HyperlinkBack */ "./extensions/Hyperlink/HyperlinkBack.js");




var aveh = AutodeskNamespace('Autodesk.Viewing.Extensions.Hyperlink'),
av = Autodesk.Viewing,
ave = Autodesk.Viewing.Extensions,
avp = Autodesk.Viewing.Private,
avu = Autodesk.Viewing.UI;

/**
                            * Panel displayed on top of the viewer displaying an hint (either a URL or a Thumbnail) of where the
                            * hyperlink will be redirecting the user into.
                            * 
                            * URLs will open in a new tab, while thumbnails are shown for models referenced by the same document.
                            * 
                            * @param {*} hyperlinkTool 
                            * @param {*} viewer 
                            * @param {*} position 
                            * @param {*} intersectPoint 
                            * @param {*} title 
                            * @param {*} link 
                            * @param {*} viewableID 
                            * @param {*} dbId 
                            * @param {*} item 
                            * @param {*} callback 
                            */
function HyperlinkPanel(hyperlinkTool, viewer, position, intersectPoint, title, link, viewableID, dbId, item, callback) {
  var self = this;
  this.viewer = viewer;

  this.container = document.createElement("div");
  this.container.className = "hyperlink-container";
  viewer.container.appendChild(this.container);

  this.container.style.left = position.x + "px";
  this.container.style.top = position.y - 70 + "px"; // add the offset to let the triangle point to the position

  this.intersectPoint = intersectPoint; // for updating the panel position when camera is changed.
  this.dbId = dbId;

  // triangle
  this.triangle = document.createElement("div");
  this.triangle.classList.add("hyperlink-container-triangle");
  this.container.appendChild(this.triangle);

  // panel
  this.panel = document.createElement("div");
  this.panel.classList.add("docking-panel");
  this.panel.classList.add("docking-panel-container-solid-color-a");
  this.panel.classList.add("hyperlink-panel");
  this.container.appendChild(this.panel);

  // title
  this.title = document.createElement("div");
  this.title.className = "hyperlink-panel-title";
  if (title) {
    this.title.textContent = title;
  } else
  {
    this.title.setAttribute("data-i18n", "External Link");
    this.title.textContent = av.i18n.translate("External Link");
  }
  this.panel.appendChild(this.title);

  function onGetThumbnail(thumbnailURL) {
    self.thumbnail.src = thumbnailURL;
  }
  if (item) {
    // thumbnail
    this.panel.classList.add("thumbnail");
    this.thumbnail = document.createElement("img");
    this.thumbnail.className = "hyperlink-panel-thumbnail";
    callback(dbId, item, onGetThumbnail);
    this.panel.appendChild(this.thumbnail);
  } else
  {
    // external link
    this.panel.classList.add("link");
    this.externalLink = document.createElement("div");
    this.externalLink.className = "hyperlink-panel-external-link";
    this.externalLink.textContent = link;
    this.panel.appendChild(this.externalLink);
  }

  // view button
  this.viewButton = document.createElement("div");
  this.viewButton.className = "docking-panel-primary-button";
  this.viewButton.setAttribute("data-i18n", "View");
  this.viewButton.textContent = av.i18n.translate("View");
  this.panel.appendChild(this.viewButton);
  this.viewButton.addEventListener('click', function () {
    self.uninitialize();
    hyperlinkTool.panel = null;
    if (viewer.__hyperlinkBack) {
      viewer.__hyperlinkBack.uninitialize();
      viewer.__hyperlinkBack = null;
    }
    var currItem = viewer.model.getDocumentNode();
    hyperlinkTool.navigateToLink(link, item);
    if (item) {
      viewer.__hyperlinkBack = new _HyperlinkBack__WEBPACK_IMPORTED_MODULE_0__["HyperlinkBack"](hyperlinkTool, viewer, currItem);
    }
  });

  // Set the triangle's position
  this.triangle.style.bottom = this.container.clientHeight - 85 + "px";

  this.boundsCheck();
};

HyperlinkPanel.prototype.uninitialize = function () {
  this.viewer.container.removeChild(this.container);
  this.container = null;
};

HyperlinkPanel.prototype.boundsCheck = function () {
  var containerBounds = this.viewer.navigation.getScreenViewport();
  var wi = this.container.clientWidth;
  var hi = this.container.clientHeight;
  var x1 = parseInt(this.container.style.left, 10);
  var y1 = parseInt(this.container.style.top, 10);

  var x2 = x1,y2 = y1;
  if (x1 < 0)
  x2 = 0;
  if (y1 < 0)
  y2 = 0;
  if (containerBounds.width < x1 + wi) {
    x2 = containerBounds.width - wi;
  }
  if (containerBounds.height < y1 + hi) {
    y2 = containerBounds.height - hi;
  }

  var distance = this.viewer.navigation.getEyeVector().length();
  var delta = this.viewer.impl.clientToViewport(x1, y1);
  var on = this.viewer.impl.clientToViewport(x2, y2);
  delta.subVectors(delta, on);
  this.viewer.navigation.panRelative(delta.x / 2, delta.y / 2, distance);

  this.container.style.left = x2 + "px";
  this.container.style.top = y2 + "px";
};

HyperlinkPanel.prototype.updatePosition = function () {
  var camera = this.viewer.navigation.getCamera();
  var containerBounds = this.viewer.navigation.getScreenViewport();

  var p = new THREE.Vector3().copy(this.intersectPoint);
  p.project(camera);

  var x = Math.round((p.x + 1) / 2 * containerBounds.width);
  var y = Math.round((-p.y + 1) / 2 * containerBounds.height);

  this.container.style.left = x + "px";
  this.container.style.top = y - 70 + "px"; // add the offset to let the triangle point to the position
};

aveh.HyperlinkPanel = HyperlinkPanel;

/***/ }),

/***/ "./extensions/Hyperlink/HyperlinkTool.js":
/*!***********************************************!*\
  !*** ./extensions/Hyperlink/HyperlinkTool.js ***!
  \***********************************************/
/*! exports provided: HyperlinkTool */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HyperlinkTool", function() { return HyperlinkTool; });
/* harmony import */ var _HyperlinkGui__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./HyperlinkGui */ "./extensions/Hyperlink/HyperlinkGui.js");


var av = Autodesk.Viewing;
var avp = av.Private;
var aveh = AutodeskNamespace('Autodesk.Viewing.Extensions.Hyperlink');



function HyperlinkTool(viewer, config) {
  av.ToolInterface.call(this);
  this.names = ['hyperlink'];

  var self = this;

  var _dbId = -1;
  var _dragging = false;
  var _linkCache2d = {};
  var _linkCache3d = {};
  var _tooltip = null;
  var _dbIdToIndex = null;

  var _stringDbIds = null;
  var _stringBoxes = null;
  var _thumbnailCache = {};

  var _bBoxOverlayName = 'Hyperlink-bBox';
  var _bBoxMaterial = null;
  var _bBoxSelectOverlayName = 'Hyperlink-bBox-select';
  var _bBoxSelectMaterial = null;
  var _meshSelected = null;

  this.panel = null; // hyperlink panel
  //this.back = null; // hyperlink back button

  /**
   * {number} Hexadecimal color for hyperlink. Default is 0x03a9f4.
   */
  this.fillColor = config.hyperlinkColor || 0x03a9f4;

  /**
                                                       * {number} Hyperlink opacity property. 1 is opaque, 0 is transparent.
                                                       */
  this.opacity = config.hyperlinkOpacity || 0.4;

  /**
                                                  * {number} Hexadecimal color for selected hyperlinks. Default is 0xff7f50.
                                                  */
  this.selectionFillColor = config.hyperlinkColorSelection || 0x708cde;

  /**
                                                                         * {number} Hyperlink opacity property. 1 is opaque, 0 is transparent.
                                                                         */
  this.selectedOpacity = config.hyperlinkOpacitySelected || 0.4;

  /**
                                                                  * {number} Padding added to the hyperlink rectangle.
                                                                  */
  this.rectanglePadding = config.hyperlinkPadding || 0.5;


  var _showTooltip = function _showTooltip(x, y, intersectPoint) {
    if (!_tooltip) {
      _tooltip = document.createElement('div');
      viewer.container.appendChild(_tooltip);

      _tooltip.setAttribute("data-i18n", "Ctrl + Click to preview the link");
      _tooltip.textContent = av.i18n.translate("Ctrl + Click to preview the link");
    }
    _tooltip.className = 'hyperlink-tooltip';
    _tooltip.style.top = y + 20 + 'px';
    _tooltip.style.left = x + 20 + 'px';
    _tooltip.intersectPoint = intersectPoint;
  };

  var _hideTooltip = function _hideTooltip() {
    if (_tooltip) {
      viewer.container.removeChild(_tooltip);
      _tooltip = null;
    }
  };

  var _updateTooltipPosition = function _updateTooltipPosition() {
    if (_tooltip) {
      var camera = viewer.navigation.getCamera();
      var containerBounds = viewer.navigation.getScreenViewport();

      var p = new THREE.Vector3().copy(_tooltip.intersectPoint);
      p.project(camera);

      var x = Math.round((p.x + 1) / 2 * containerBounds.width);
      var y = Math.round((-p.y + 1) / 2 * containerBounds.height);

      _tooltip.style.left = x + 20 + "px";
      _tooltip.style.top = y + 20 + "px";
    }
  };

  var _onGeometryLoaded = function _onGeometryLoaded(event) {
    viewer.removeEventListener(av.GEOMETRY_LOADED_EVENT, _onGeometryLoaded);
    self.loadHyperlinks();
  };

  var _onCameraChange = function _onCameraChange() {
    if (self.panel) {
      self.panel.updatePosition();
    }
    _updateTooltipPosition();
  };

  this.activate = function (name) {
    if (viewer.model && viewer.model.isLoadDone()) {
      self.loadHyperlinks();
    } else
    {
      viewer.addEventListener(av.GEOMETRY_LOADED_EVENT, _onGeometryLoaded);
    }
    viewer.addEventListener(av.CAMERA_CHANGE_EVENT, _onCameraChange);
  };

  this.deactivate = function (name) {
    viewer.removeEventListener(av.CAMERA_CHANGE_EVENT, _onCameraChange);
    viewer.removeEventListener(av.GEOMETRY_LOADED_EVENT, _onGeometryLoaded);

    _linkCache2d = {};
    _linkCache3d = {};
    _hideTooltip();
    if (this.panel) {
      this.panel.uninitialize();
      this.panel = null;
    }
    if (viewer.__hyperlinkBack) {
      viewer.__hyperlinkBack.uninitialize();
      viewer.__hyperlinkBack = null;
    }
    viewer.impl.clearOverlay(_bBoxOverlayName);
    viewer.impl.clearOverlay(_bBoxSelectOverlayName);
  };

  this.update = function (timestamp) {
    return false;
  };

  this.handleSingleClick = function (event, button) {

    this.clearSelection();
    if (this.panel) {
      this.panel.uninitialize();
      this.panel = null;
    }

    var docNode = viewer.model.getDocumentNode();
    var viewableID = null;
    if (docNode) {
      viewableID = docNode.data.viewableID;
    }
    var position = new THREE.Vector2(event.canvasX, event.canvasY);

    // 2D
    if (viewer.model.is2d()) {

      var viewportCoords = viewer.impl.clientToViewport(event.canvasX, event.canvasY);
      var intersectPoint = viewer.impl.intersectGroundViewport(viewportCoords);

      for (var index in _linkCache2d) {

        if (!_linkCache2d.hasOwnProperty(index))
        continue;

        var hyperLink = _linkCache2d[index];
        var x = intersectPoint.x;
        var y = intersectPoint.y;
        if (x >= hyperLink.bBox[0] && x <= hyperLink.bBox[2] && y >= hyperLink.bBox[1] && y <= hyperLink.bBox[3]) {
          // Internal links
          if (hyperLink.node) {
            var title = hyperLink.node.data.name;
            this.panel = new _HyperlinkGui__WEBPACK_IMPORTED_MODULE_0__["HyperlinkPanel"](self, viewer, position, intersectPoint, title, hyperLink.link, viewableID, hyperLink.dbId, hyperLink.node.data, this.getThumbnail);
          }
          // external links
          else {
              this.panel = new _HyperlinkGui__WEBPACK_IMPORTED_MODULE_0__["HyperlinkPanel"](self, viewer, position, intersectPoint, null, hyperLink.link, viewableID);
            }
          this.highlightSelection(hyperLink.bBoxMesh);
          return true;
        }
      }

      return false;
    }

    // 3D
    if (viewer.model.is3d()) {

      var result = viewer.impl.hitTest(event.canvasX, event.canvasY, false);
      if (!result)
      return false;

      if (event.ctrlKey && _linkCache3d[_dbId]) {
        this.controller.setIsLocked(false);
        _hideTooltip();
        var hyperLink = _linkCache3d[_dbId];
        // Internal links
        if (hyperLink.node) {
          var title = hyperLink.node.data.name;
          this.panel = new _HyperlinkGui__WEBPACK_IMPORTED_MODULE_0__["HyperlinkPanel"](self, viewer, position, result.intersectPoint, title, hyperLink.link, viewableID, _dbId, hyperLink.node.data, this.getThumbnail);
        }
        // external links
        else {
            this.panel = new _HyperlinkGui__WEBPACK_IMPORTED_MODULE_0__["HyperlinkPanel"](self, viewer, position, result.intersectPoint, null, hyperLink.link, viewableID, _dbId);
          }
        return true;
      }
    }

    return false;
  };

  this.handleButtonDown = function (event, button) {
    _dragging = true;
    return false;
  };

  this.handleButtonUp = function (event, button) {
    _dragging = false;
    return false;
  };

  /**
      * Specialize base class implementation
      */
  this.handleMouseMove = function (event) {
    if (_dragging) {
      return;
    }

    // 3D
    if (viewer.model && !viewer.model.is2d()) {
      var result = viewer.impl.hitTest(event.canvasX, event.canvasY, false);
      if (result) {
        var dbId = result.dbId;
        if (dbId != _dbId) {
          _dbId = dbId;
          _hideTooltip();
        }

        // Don't show tooltip for the same object when the popup is shown
        if (this.panel && this.panel.dbId === dbId) {
          return;
        }

        // We're checking the hyperlinks lazily which means that their 1st appearance may be delayed.
        // If this is a problem, consider preloading hyperlinks during HyperlinkTool activation.
        if (_linkCache3d.hasOwnProperty(_dbId)) {
          if (_linkCache3d[_dbId]) {
            _showTooltip(event.canvasX, event.canvasY, result.intersectPoint);
          }
        } else
        {
          _linkCache3d[_dbId] = null;
          this.loadHyperlink3d(_dbId, event.canvasX, event.canvasY, result.intersectPoint);
        }
      } else
      {
        _hideTooltip();
      }
    }
    return false;
  };

  this.getCursor = function () {
    return _tooltip ? 'pointer' : null;
  };

  /**
      * Load hyperlinks for 2D models.
      */
  this.loadHyperlinks = function () {

    var data = viewer.model.getData();
    _stringDbIds = data.stringDbIds;
    _stringBoxes = data.stringBoxes;
    _linkCache2d = {};

    // We only need to check the dbIds in stringDbIds, since
    // hyperlinks are associated with texts in 2d drawing.
    if (!_stringDbIds)
    return;

    // _stringDbIds contains duplicate dbIds and also negative dbIds, which are
    // placeholders for text-only geometry without any property database entry.
    // Need to remove the negative dbIds and delete all other duplicates.
    var uniqueDbIds = [];
    _dbIdToIndex = {};
    for (var i = 0, len = _stringDbIds.length; i < len; ++i) {

      var candidateId = _stringDbIds[i];
      if (candidateId < 1)
      continue;

      if (uniqueDbIds.indexOf(candidateId) === -1) {
        uniqueDbIds.push(candidateId);
        _dbIdToIndex[candidateId] = [];
      }

      _dbIdToIndex[candidateId].push(i);
    }

    // Ignore error function callback.
    viewer.model.getBulkProperties(uniqueDbIds, { propFilter: ['hyperlink'] }, this._onBulkProperties);
  };

  /**
      * Parses results from model.getBulkProperties() to initialize hyperlinks on-canvas.
      * 
      * @private
      */
  this._onBulkProperties = function (results) {

    // Get bubble manifest.
    var docNode = viewer.model.getDocumentNode();
    if (docNode) {
      docNode = docNode.getRootNode();
    }

    for (var i = 0, len = results.length; i < len; ++i) {
      var result = results[i];
      var dbId = result.dbId;
      var propValue = result.properties[0].displayValue;
      var linkToNode = null; // Object reference
      var link = null; // string

      // Is it a reference to another Document viewable?
      var candidates = docNode ? docNode.search({ 'viewableID': propValue }) : null;
      if (candidates && candidates.length) {
        linkToNode = candidates[0];
      }
      // Or a URL, maybe?
      if (!linkToNode && this._isURL(propValue)) {
        link = propValue;
      }

      if (!linkToNode && !link)
      continue;

      // Cache it
      var indices = _dbIdToIndex[dbId];
      for (var x = 0; x < indices.length; ++x) {

        var index = indices[x];
        _linkCache2d[index] = {
          dbId: dbId,
          link: link,
          node: linkToNode };


        // Highlight the bounding box of text with hyperlink
        this.highlightText(index);
      }

    }
  }.bind(this);

  /**
                 * TODO: Refactor to common place.
                 * 
                 * @private
                 */
  this._isURL = function (str) {

    //
    // We could have a complex RegExp, but I'm going with a simple check for URLs.
    //
    if (typeof str !== 'string')
    return;

    // check http protocol, it's the only one we care about.
    var protocol = str.substr(0, 4).toLowerCase();
    if (protocol === 'http')
    return true;

    // Find first '/' ...
    var firstSlash = str.indexOf('/');
    if (firstSlash !== -1) {
      // ... and get rid of the rest...
      str = str.substr(0, firstSlash);
    }

    // If there is a slash, check that str has at least 1 dot. Example: autodesk.com/something
    var dotCount = str.split('.').length;
    if (firstSlash > 0 && dotCount > 0)
    return true;

    // If there is no slash, check that the url has at least 2 dots. Example: www.autodesk.com
    if (firstSlash === -1 && dotCount > 1)
    return true;

    // Add more checks as needed...

    return false;
  };

  this.navigateToLink = function (link, item) {

    if (link) {
      window.open(link);
      return;
    }

    if (item) {
      // Relies on ViewingApplication to navigate the Viewer into the new viewable.
      viewer.dispatchEvent({ type: av.HYPERLINK_EVENT, data: { item: item } });
      return;
    }
  };

  this.loadHyperlink3d = function (dbId, x, y, intersectPoint) {
    viewer.getProperties(dbId, function (result) {
      var props = result.properties;
      for (var i = 0, len = props.length; i < len; i++) {
        var prop = props[i];
        if (prop.displayCategory === '__hyperlink__') {
          var linkToNode = null;
          var link = prop.displayValue;
          var docNode = viewer.model.getDocumentNode();
          if (docNode) {
            docNode = docNode.getRootNode();
            var candidates = docNode.search({ 'viewableID': link });
            if (candidates && candidates.length) {
              linkToNode = candidates[0];
            }
          }
          _linkCache3d[dbId] = {
            link: link,
            node: linkToNode };


          _showTooltip(x, y, intersectPoint);

          break;
        }
      }
    });
  };

  this.getHyperlinks = function () {
    return _linkCache;
  };

  /**
      * @param {string} item - Document item.
      */
  this.getThumbnail = function (dbId, item, callback) {
    if (_thumbnailCache.hasOwnProperty(dbId)) {
      callback(_thumbnailCache[dbId]);
      return;
    }

    var data = {
      urn: viewer.model.getData().urn,
      width: 200,
      height: 200,
      guid: encodeURIComponent(item.guid),
      acmsession: viewer.model.getData().acmSessionId };


    var onSuccess = function onSuccess(response) {
      var reader = new FileReader();
      reader.onload = function (e) {
        var thumbnailURL = e.target.result;
        _thumbnailCache[dbId] = thumbnailURL;
        callback(thumbnailURL);
      };
      reader.readAsDataURL(response);
    };

    var options = {
      responseType: 'blob',
      skipAssetCallback: true,
      size: data.width, //Ignore the height, they are the same.
      guid: data.guid,
      acmsession: data.acmsession };


    var urlpath = "urn:" + data.urn; //HACK: Adding urn: makes the ViewingServiceXhr accept this as a viewing service request.
    avp.ViewingService.getThumbnail(av.initLoadContext(), urlpath, onSuccess, null, options);
  };

  this.highlightText = function (index) {
    var padding = this.rectanglePadding;
    var minX = _stringBoxes[index * 4] - padding;
    var minY = _stringBoxes[index * 4 + 1] - padding;
    var maxX = _stringBoxes[index * 4 + 2] + padding;
    var maxY = _stringBoxes[index * 4 + 3] + padding;
    _linkCache2d[index].bBox = [minX, minY, maxX, maxY];

    // draw a rectangle with these values.
    this.addRectangle(index, minX, minY, maxX, maxY);
  };

  this.addRectangle = function (index, minX, minY, maxX, maxY) {

    var z = 0;
    var vA = new THREE.Vector3(minX, minY, z);
    var vB = new THREE.Vector3(maxX, minY, z);
    var vC = new THREE.Vector3(maxX, maxY, z);
    var vD = new THREE.Vector3(minX, maxY, z);

    var geom = new THREE.Geometry();
    geom.vertices.push(vA);
    geom.vertices.push(vB);
    geom.vertices.push(vC);
    geom.vertices.push(vD);

    geom.faces.push(new THREE.Face3(0, 1, 2));
    geom.faces.push(new THREE.Face3(0, 3, 2));

    if (!_bBoxMaterial) {
      var color = this.fillColor;
      var opacity = this.opacity;

      _bBoxMaterial = new THREE.MeshBasicMaterial({
        color: color,
        opacity: opacity,
        transparent: true,
        depthTest: false,
        depthWrite: false,
        side: THREE.DoubleSide });


      viewer.impl.createOverlayScene(_bBoxOverlayName);
    }

    var mesh = _linkCache2d[index].bBoxMesh = new THREE.Mesh(geom, _bBoxMaterial, true);

    viewer.impl.addOverlay(_bBoxOverlayName, mesh);

  };

  this.highlightSelection = function (mesh) {
    _meshSelected = mesh;
    viewer.impl.removeOverlay(_bBoxOverlayName, mesh);

    if (!_bBoxSelectMaterial) {
      var color = this.selectionFillColor;;
      var opacity = this.selectedOpacity;

      _bBoxSelectMaterial = new THREE.MeshBasicMaterial({
        color: color,
        opacity: opacity,
        transparent: true,
        depthTest: false,
        depthWrite: false,
        side: THREE.DoubleSide });


      viewer.impl.createOverlayScene(_bBoxSelectOverlayName);
    }

    var newMesh = new THREE.Mesh(mesh.geometry, _bBoxSelectMaterial);
    viewer.impl.addOverlay(_bBoxSelectOverlayName, newMesh);
  };

  this.clearSelection = function () {
    if (_meshSelected) {
      viewer.impl.clearOverlay(_bBoxSelectOverlayName);

      viewer.impl.addOverlay(_bBoxOverlayName, _meshSelected);
      _meshSelected = null;
    }
  };

};

aveh.HyperlinkTool = HyperlinkTool;

/***/ }),

/***/ "./node_modules/css-loader/index.js!./extensions/Hyperlink/Hyperlink.css":
/*!**********************************************************************!*\
  !*** ./node_modules/css-loader!./extensions/Hyperlink/Hyperlink.css ***!
  \**********************************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

exports = module.exports = __webpack_require__(/*! ../../node_modules/css-loader/lib/css-base.js */ "./node_modules/css-loader/lib/css-base.js")(false);
// imports


// module
exports.push([module.i, ".adsk-viewing-viewer .hyperlink-tooltip {\n    display: block;\n    position: absolute;\n    left: 0px;\n    top: 0px;\n    padding: 4px;\n    background-color: rgba(196, 196, 196, 0.8);\n    box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.3);\n    font-size: 12px;\n    text-align: center;\n    line-height: 1.2;\n    white-space: nowrap;\n}\n\n.adsk-viewing-viewer .hyperlink-container {\n    position: absolute;\n    width : 250px;\n    z-index: 10;\n}\n\n.adsk-viewing-viewer .hyperlink-container-triangle {\n    position: relative;\n    display: inline-block;\n    width: 0;\n    height: 0;\n    border-top: 11px solid transparent;\n    border-bottom: 11px solid transparent;\n    z-index: 3;\n}\n\n.adsk-viewing-viewer .hyperlink-panel {\n    display: inline-block;\n    width : 300px;\n}\n\n.adsk-viewing-viewer .hyperlink-panel.thumbnail {\n    width: 220px;\n}\n\n.adsk-viewing-viewer .hyperlink-panel-title {\n    padding: 10px 5px 5px 10px;\n}\n\n.adsk-viewing-viewer .hyperlink-panel-thumbnail {\n    display: block;\n    background : #FFFFFF;\n    margin: 3px 0px 10px 10px;\n    width : 200px;\n    height : 200px;\n}\n\n.adsk-viewing-viewer .hyperlink-panel-external-link {\n    font-size: 12px;\n    margin: 5px 10px 10px 10px;\n    padding: 5px 5px 5px 5px;\n    max-height: 300px;\n    word-break: break-all;\n\n    -webkit-user-select: text;\n    -khtml-user-select: text;\n    -moz-user-select: text;\n    -ms-user-select: text;\n    user-select: text;\n}\n\n.adsk-viewing-viewer .hyperlink-panel-view-button {\n    background-color : #6892C6;\n    /*height : 27px;*/\n    text-align: center;\n    padding: 7px 0px;\n    margin: 0px 10px 10px 10px;\n    border-radius : 1px;\n    -moz-border-radius : 1px;\n    -webkit-border-radius : 1px;\n    cursor: pointer;\n}\n\n.adsk-viewing-viewer .hyperlink-back {\n    position: absolute;\n    width : 106px;\n    height : 38px;\n    left: 10px;\n    top: 10px;\n}\n\n.adsk-viewing-viewer .hyperlink-back-button {\n    top: 0;\n    left: 0;\n    width: 70%;\n    cursor: pointer;\n    text-align: center;\n    position: absolute;\n}\n\n.adsk-viewing-viewer .docking-panel-close.hyperlink-back-closer {\n    width: 30%;\n    cursor: pointer;\n    background-position: 3px 12px;\n    height: 100%;\n}", ""]);

// exports


/***/ }),

/***/ "./node_modules/css-loader/lib/css-base.js":
/*!*************************************************!*\
  !*** ./node_modules/css-loader/lib/css-base.js ***!
  \*************************************************/
/*! no static exports found */
/***/ (function(module, exports) {

/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Tobias Koppers @sokra
*/
// css base code, injected by the css-loader
module.exports = function(useSourceMap) {
	var list = [];

	// return the list of modules as css string
	list.toString = function toString() {
		return this.map(function (item) {
			var content = cssWithMappingToString(item, useSourceMap);
			if(item[2]) {
				return "@media " + item[2] + "{" + content + "}";
			} else {
				return content;
			}
		}).join("");
	};

	// import a list of modules into the list
	list.i = function(modules, mediaQuery) {
		if(typeof modules === "string")
			modules = [[null, modules, ""]];
		var alreadyImportedModules = {};
		for(var i = 0; i < this.length; i++) {
			var id = this[i][0];
			if(typeof id === "number")
				alreadyImportedModules[id] = true;
		}
		for(i = 0; i < modules.length; i++) {
			var item = modules[i];
			// skip already imported module
			// this implementation is not 100% perfect for weird media query combinations
			//  when a module is imported multiple times with different media queries.
			//  I hope this will never occur (Hey this way we have smaller bundles)
			if(typeof item[0] !== "number" || !alreadyImportedModules[item[0]]) {
				if(mediaQuery && !item[2]) {
					item[2] = mediaQuery;
				} else if(mediaQuery) {
					item[2] = "(" + item[2] + ") and (" + mediaQuery + ")";
				}
				list.push(item);
			}
		}
	};
	return list;
};

function cssWithMappingToString(item, useSourceMap) {
	var content = item[1] || '';
	var cssMapping = item[3];
	if (!cssMapping) {
		return content;
	}

	if (useSourceMap && typeof btoa === 'function') {
		var sourceMapping = toComment(cssMapping);
		var sourceURLs = cssMapping.sources.map(function (source) {
			return '/*# sourceURL=' + cssMapping.sourceRoot + source + ' */'
		});

		return [content].concat(sourceURLs).concat([sourceMapping]).join('\n');
	}

	return [content].join('\n');
}

// Adapted from convert-source-map (MIT)
function toComment(sourceMap) {
	// eslint-disable-next-line no-undef
	var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap))));
	var data = 'sourceMappingURL=data:application/json;charset=utf-8;base64,' + base64;

	return '/*# ' + data + ' */';
}


/***/ }),

/***/ "./node_modules/style-loader/lib/addStyles.js":
/*!****************************************************!*\
  !*** ./node_modules/style-loader/lib/addStyles.js ***!
  \****************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Tobias Koppers @sokra
*/

var stylesInDom = {};

var	memoize = function (fn) {
	var memo;

	return function () {
		if (typeof memo === "undefined") memo = fn.apply(this, arguments);
		return memo;
	};
};

var isOldIE = memoize(function () {
	// Test for IE <= 9 as proposed by Browserhacks
	// @see http://browserhacks.com/#hack-e71d8692f65334173fee715c222cb805
	// Tests for existence of standard globals is to allow style-loader
	// to operate correctly into non-standard environments
	// @see https://github.com/webpack-contrib/style-loader/issues/177
	return window && document && document.all && !window.atob;
});

var getTarget = function (target, parent) {
  if (parent){
    return parent.querySelector(target);
  }
  return document.querySelector(target);
};

var getElement = (function (fn) {
	var memo = {};

	return function(target, parent) {
                // If passing function in options, then use it for resolve "head" element.
                // Useful for Shadow Root style i.e
                // {
                //   insertInto: function () { return document.querySelector("#foo").shadowRoot }
                // }
                if (typeof target === 'function') {
                        return target();
                }
                if (typeof memo[target] === "undefined") {
			var styleTarget = getTarget.call(this, target, parent);
			// Special case to return head of iframe instead of iframe itself
			if (window.HTMLIFrameElement && styleTarget instanceof window.HTMLIFrameElement) {
				try {
					// This will throw an exception if access to iframe is blocked
					// due to cross-origin restrictions
					styleTarget = styleTarget.contentDocument.head;
				} catch(e) {
					styleTarget = null;
				}
			}
			memo[target] = styleTarget;
		}
		return memo[target]
	};
})();

var singleton = null;
var	singletonCounter = 0;
var	stylesInsertedAtTop = [];

var	fixUrls = __webpack_require__(/*! ./urls */ "./node_modules/style-loader/lib/urls.js");

module.exports = function(list, options) {
	if (typeof DEBUG !== "undefined" && DEBUG) {
		if (typeof document !== "object") throw new Error("The style-loader cannot be used in a non-browser environment");
	}

	options = options || {};

	options.attrs = typeof options.attrs === "object" ? options.attrs : {};

	// Force single-tag solution on IE6-9, which has a hard limit on the # of <style>
	// tags it will allow on a page
	if (!options.singleton && typeof options.singleton !== "boolean") options.singleton = isOldIE();

	// By default, add <style> tags to the <head> element
        if (!options.insertInto) options.insertInto = "head";

	// By default, add <style> tags to the bottom of the target
	if (!options.insertAt) options.insertAt = "bottom";

	var styles = listToStyles(list, options);

	addStylesToDom(styles, options);

	return function update (newList) {
		var mayRemove = [];

		for (var i = 0; i < styles.length; i++) {
			var item = styles[i];
			var domStyle = stylesInDom[item.id];

			domStyle.refs--;
			mayRemove.push(domStyle);
		}

		if(newList) {
			var newStyles = listToStyles(newList, options);
			addStylesToDom(newStyles, options);
		}

		for (var i = 0; i < mayRemove.length; i++) {
			var domStyle = mayRemove[i];

			if(domStyle.refs === 0) {
				for (var j = 0; j < domStyle.parts.length; j++) domStyle.parts[j]();

				delete stylesInDom[domStyle.id];
			}
		}
	};
};

function addStylesToDom (styles, options) {
	for (var i = 0; i < styles.length; i++) {
		var item = styles[i];
		var domStyle = stylesInDom[item.id];

		if(domStyle) {
			domStyle.refs++;

			for(var j = 0; j < domStyle.parts.length; j++) {
				domStyle.parts[j](item.parts[j]);
			}

			for(; j < item.parts.length; j++) {
				domStyle.parts.push(addStyle(item.parts[j], options));
			}
		} else {
			var parts = [];

			for(var j = 0; j < item.parts.length; j++) {
				parts.push(addStyle(item.parts[j], options));
			}

			stylesInDom[item.id] = {id: item.id, refs: 1, parts: parts};
		}
	}
}

function listToStyles (list, options) {
	var styles = [];
	var newStyles = {};

	for (var i = 0; i < list.length; i++) {
		var item = list[i];
		var id = options.base ? item[0] + options.base : item[0];
		var css = item[1];
		var media = item[2];
		var sourceMap = item[3];
		var part = {css: css, media: media, sourceMap: sourceMap};

		if(!newStyles[id]) styles.push(newStyles[id] = {id: id, parts: [part]});
		else newStyles[id].parts.push(part);
	}

	return styles;
}

function insertStyleElement (options, style) {
	var target = getElement(options.insertInto)

	if (!target) {
		throw new Error("Couldn't find a style target. This probably means that the value for the 'insertInto' parameter is invalid.");
	}

	var lastStyleElementInsertedAtTop = stylesInsertedAtTop[stylesInsertedAtTop.length - 1];

	if (options.insertAt === "top") {
		if (!lastStyleElementInsertedAtTop) {
			target.insertBefore(style, target.firstChild);
		} else if (lastStyleElementInsertedAtTop.nextSibling) {
			target.insertBefore(style, lastStyleElementInsertedAtTop.nextSibling);
		} else {
			target.appendChild(style);
		}
		stylesInsertedAtTop.push(style);
	} else if (options.insertAt === "bottom") {
		target.appendChild(style);
	} else if (typeof options.insertAt === "object" && options.insertAt.before) {
		var nextSibling = getElement(options.insertAt.before, target);
		target.insertBefore(style, nextSibling);
	} else {
		throw new Error("[Style Loader]\n\n Invalid value for parameter 'insertAt' ('options.insertAt') found.\n Must be 'top', 'bottom', or Object.\n (https://github.com/webpack-contrib/style-loader#insertat)\n");
	}
}

function removeStyleElement (style) {
	if (style.parentNode === null) return false;
	style.parentNode.removeChild(style);

	var idx = stylesInsertedAtTop.indexOf(style);
	if(idx >= 0) {
		stylesInsertedAtTop.splice(idx, 1);
	}
}

function createStyleElement (options) {
	var style = document.createElement("style");

	if(options.attrs.type === undefined) {
		options.attrs.type = "text/css";
	}

	if(options.attrs.nonce === undefined) {
		var nonce = getNonce();
		if (nonce) {
			options.attrs.nonce = nonce;
		}
	}

	addAttrs(style, options.attrs);
	insertStyleElement(options, style);

	return style;
}

function createLinkElement (options) {
	var link = document.createElement("link");

	if(options.attrs.type === undefined) {
		options.attrs.type = "text/css";
	}
	options.attrs.rel = "stylesheet";

	addAttrs(link, options.attrs);
	insertStyleElement(options, link);

	return link;
}

function addAttrs (el, attrs) {
	Object.keys(attrs).forEach(function (key) {
		el.setAttribute(key, attrs[key]);
	});
}

function getNonce() {
	if (false) {}

	return __webpack_require__.nc;
}

function addStyle (obj, options) {
	var style, update, remove, result;

	// If a transform function was defined, run it on the css
	if (options.transform && obj.css) {
	    result = typeof options.transform === 'function'
		 ? options.transform(obj.css) 
		 : options.transform.default(obj.css);

	    if (result) {
	    	// If transform returns a value, use that instead of the original css.
	    	// This allows running runtime transformations on the css.
	    	obj.css = result;
	    } else {
	    	// If the transform function returns a falsy value, don't add this css.
	    	// This allows conditional loading of css
	    	return function() {
	    		// noop
	    	};
	    }
	}

	if (options.singleton) {
		var styleIndex = singletonCounter++;

		style = singleton || (singleton = createStyleElement(options));

		update = applyToSingletonTag.bind(null, style, styleIndex, false);
		remove = applyToSingletonTag.bind(null, style, styleIndex, true);

	} else if (
		obj.sourceMap &&
		typeof URL === "function" &&
		typeof URL.createObjectURL === "function" &&
		typeof URL.revokeObjectURL === "function" &&
		typeof Blob === "function" &&
		typeof btoa === "function"
	) {
		style = createLinkElement(options);
		update = updateLink.bind(null, style, options);
		remove = function () {
			removeStyleElement(style);

			if(style.href) URL.revokeObjectURL(style.href);
		};
	} else {
		style = createStyleElement(options);
		update = applyToTag.bind(null, style);
		remove = function () {
			removeStyleElement(style);
		};
	}

	update(obj);

	return function updateStyle (newObj) {
		if (newObj) {
			if (
				newObj.css === obj.css &&
				newObj.media === obj.media &&
				newObj.sourceMap === obj.sourceMap
			) {
				return;
			}

			update(obj = newObj);
		} else {
			remove();
		}
	};
}

var replaceText = (function () {
	var textStore = [];

	return function (index, replacement) {
		textStore[index] = replacement;

		return textStore.filter(Boolean).join('\n');
	};
})();

function applyToSingletonTag (style, index, remove, obj) {
	var css = remove ? "" : obj.css;

	if (style.styleSheet) {
		style.styleSheet.cssText = replaceText(index, css);
	} else {
		var cssNode = document.createTextNode(css);
		var childNodes = style.childNodes;

		if (childNodes[index]) style.removeChild(childNodes[index]);

		if (childNodes.length) {
			style.insertBefore(cssNode, childNodes[index]);
		} else {
			style.appendChild(cssNode);
		}
	}
}

function applyToTag (style, obj) {
	var css = obj.css;
	var media = obj.media;

	if(media) {
		style.setAttribute("media", media)
	}

	if(style.styleSheet) {
		style.styleSheet.cssText = css;
	} else {
		while(style.firstChild) {
			style.removeChild(style.firstChild);
		}

		style.appendChild(document.createTextNode(css));
	}
}

function updateLink (link, options, obj) {
	var css = obj.css;
	var sourceMap = obj.sourceMap;

	/*
		If convertToAbsoluteUrls isn't defined, but sourcemaps are enabled
		and there is no publicPath defined then lets turn convertToAbsoluteUrls
		on by default.  Otherwise default to the convertToAbsoluteUrls option
		directly
	*/
	var autoFixUrls = options.convertToAbsoluteUrls === undefined && sourceMap;

	if (options.convertToAbsoluteUrls || autoFixUrls) {
		css = fixUrls(css);
	}

	if (sourceMap) {
		// http://stackoverflow.com/a/26603875
		css += "\n/*# sourceMappingURL=data:application/json;base64," + btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))) + " */";
	}

	var blob = new Blob([css], { type: "text/css" });

	var oldSrc = link.href;

	link.href = URL.createObjectURL(blob);

	if(oldSrc) URL.revokeObjectURL(oldSrc);
}


/***/ }),

/***/ "./node_modules/style-loader/lib/urls.js":
/*!***********************************************!*\
  !*** ./node_modules/style-loader/lib/urls.js ***!
  \***********************************************/
/*! no static exports found */
/***/ (function(module, exports) {


/**
 * When source maps are enabled, `style-loader` uses a link element with a data-uri to
 * embed the css on the page. This breaks all relative urls because now they are relative to a
 * bundle instead of the current page.
 *
 * One solution is to only use full urls, but that may be impossible.
 *
 * Instead, this function "fixes" the relative urls to be absolute according to the current page location.
 *
 * A rudimentary test suite is located at `test/fixUrls.js` and can be run via the `npm test` command.
 *
 */

module.exports = function (css) {
  // get current location
  var location = typeof window !== "undefined" && window.location;

  if (!location) {
    throw new Error("fixUrls requires window.location");
  }

	// blank or null?
	if (!css || typeof css !== "string") {
	  return css;
  }

  var baseUrl = location.protocol + "//" + location.host;
  var currentDir = baseUrl + location.pathname.replace(/\/[^\/]*$/, "/");

	// convert each url(...)
	/*
	This regular expression is just a way to recursively match brackets within
	a string.

	 /url\s*\(  = Match on the word "url" with any whitespace after it and then a parens
	   (  = Start a capturing group
	     (?:  = Start a non-capturing group
	         [^)(]  = Match anything that isn't a parentheses
	         |  = OR
	         \(  = Match a start parentheses
	             (?:  = Start another non-capturing groups
	                 [^)(]+  = Match anything that isn't a parentheses
	                 |  = OR
	                 \(  = Match a start parentheses
	                     [^)(]*  = Match anything that isn't a parentheses
	                 \)  = Match a end parentheses
	             )  = End Group
              *\) = Match anything and then a close parens
          )  = Close non-capturing group
          *  = Match anything
       )  = Close capturing group
	 \)  = Match a close parens

	 /gi  = Get all matches, not the first.  Be case insensitive.
	 */
	var fixedCss = css.replace(/url\s*\(((?:[^)(]|\((?:[^)(]+|\([^)(]*\))*\))*)\)/gi, function(fullMatch, origUrl) {
		// strip quotes (if they exist)
		var unquotedOrigUrl = origUrl
			.trim()
			.replace(/^"(.*)"$/, function(o, $1){ return $1; })
			.replace(/^'(.*)'$/, function(o, $1){ return $1; });

		// already a full url? no change
		if (/^(#|data:|http:\/\/|https:\/\/|file:\/\/\/|\s*$)/i.test(unquotedOrigUrl)) {
		  return fullMatch;
		}

		// convert the url to a full url
		var newUrl;

		if (unquotedOrigUrl.indexOf("//") === 0) {
		  	//TODO: should we add protocol?
			newUrl = unquotedOrigUrl;
		} else if (unquotedOrigUrl.indexOf("/") === 0) {
			// path should be relative to the base url
			newUrl = baseUrl + unquotedOrigUrl; // already starts with '/'
		} else {
			// path should be relative to current directory
			newUrl = currentDir + unquotedOrigUrl.replace(/^\.\//, ""); // Strip leading './'
		}

		// send back the fixed url(...)
		return "url(" + JSON.stringify(newUrl) + ")";
	});

	// send back the fixed css
	return fixedCss;
};


/***/ })

/******/ });